// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ValueValidatorBase.cs" company="">
//   
// </copyright>
// <summary>
//   The value validator base.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Skymate.Runtime.Validation
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    using Skymate.Extensions;

    /// <summary>
    ///     The value validator base.
    /// </summary>
    [Serializable]
    public abstract class ValueValidatorBase : IValueValidator
    {
        /// <summary>
        ///     Initializes a new instance of the <see cref="ValueValidatorBase" /> class.
        /// </summary>
        protected ValueValidatorBase()
        {
            this.Attributes = new Dictionary<string, object>();
        }

        /// <summary>
        ///     Gets the name.
        /// </summary>
        public virtual string Name
        {
            get
            {
                var type = this.GetType();
                if (type.IsDefined(typeof(ValidatorAttribute)))
                {
                    return type.GetCustomAttributes(typeof(ValidatorAttribute)).Cast<ValidatorAttribute>().First().Name;
                }

                return type.Name;
            }
        }

        /// <summary>
        /// Gets/sets arbitrary objects related to this object.
        ///     Gets null if given key does not exists.
        /// </summary>
        /// <param name="key">
        /// Key
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        public object this[string key]
        {
            get
            {
                return this.Attributes.GetValue<string, object>(key); /*.GetOrDefault(key);*/
            }

            set
            {
                this.Attributes[key] = value;
            }
        }

        /// <summary>
        ///     Arbitrary objects related to this object.
        /// </summary>
        public IDictionary<string, object> Attributes { get; private set; }

        /// <summary>
        /// The is valid.
        /// </summary>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public abstract bool IsValid(object value);
    }
}